
/*
 *  Copyright (c) 2015. For Intelligent Group.
 *
 */

package com.intelligent.ispc.client.core.controller;

import com.intelligent.ispc.client.core.validator.UslAndLslDto;
import com.intelligent.ispc.client.core.view.global.MainStateBar;
import com.intelligent.ispc.client.event.*;
import com.intelligent.ispc.client.utils.ApplicationBeanUtils;
import com.intelligent.ispc.client.utils.EventBusUtils;
import com.intelligent.ispc.client.utils.UIException;
import com.intelligent.ispc.common.utils.ApplicationException;
import com.intelligent.ispc.common.utils.ExceptionMessages;
import com.intelligent.ispc.constant.ProcessConstant;
import com.intelligent.ispc.core.dto.*;
import com.intelligent.ispc.core.service.ReportService;
import com.intelligent.ispc.core.service.SpcService;
import com.intelligent.ispc.core.service.SystemService;
import com.intelligent.ispc.utils.executor.ExecutorPool;
import com.intelligent.ispc.utils.executor.ExecutorTask;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.List;

/**
 * Created by Lucien.Chen on 2016/8/29.
 */
@Component
public class YieldController {

    private final Logger logger = LoggerFactory.getLogger(YieldController.class);
    @Autowired
    private ReportService reportService;
    @Autowired
    private SpcService spcService;

    @Autowired
    private SystemService systemService;

    /**
     * find yield data in new thead
     *
     * @param filePath      currten choose file
     * @param searchKeys    currten search fields
     * @param groupKeys     currten choose groups
     * @param testItemNames currten choose item
     * @param uslAndLslDto  currten usl and lsl
     */
    public void findYield(List<String> filePath, List<DynSearchFieldDto> searchKeys, List<String> groupKeys, List<String> testItemNames, UslAndLslDto uslAndLslDto) {
        boolean isWorking = ApplicationBeanUtils.getBean(MainStateBar.class).getProcessPanel().isWorking(ProcessConstant.YIELD_EXECUTE_TASK);
        if (isWorking) {
            throw new UIException("This task is already working now.");
        }
        EventBusUtils.post(new StatusBarProcessCreateTaskEvent(ProcessConstant.YIELD_EXECUTE_TASK));

        ExecutorTask task = new ExecutorTask(ProcessConstant.YIELD_EXECUTE_TASK, new ExecutorTask.Work() {
            @Override
            public void execute() {
                try {
                    YieldItemParamDto yieldItemParamDto = itemDataChangeInto(uslAndLslDto);
                    List<YieldDto> yieldDtos = reportService.getYield(filePath, searchKeys, groupKeys, testItemNames, yieldItemParamDto);

                    if (!ApplicationBeanUtils.getBean(MainStateBar.class).getProcessPanel().isProcessTaskEmpty()) {
                        EventBusUtils.post(new ExecutorTaskFinishEvent(ProcessConstant.YIELD_EXECUTE_TASK, yieldDtos));
                        EventBusUtils.post(new StatusBarProcessFinishTaskEvent(ProcessConstant.YIELD_EXECUTE_TASK, false));
                    }
                } catch (ApplicationException e) {
                    EventBusUtils.post(new StatusBarProcessChangeEvent(ProcessConstant.YIELD_EXECUTE_TASK, e.getFullMessage()).level(ProcessConstant.ERROR));
                } catch (Exception e) {
                    EventBusUtils.post(new ThrowExceptionEvent(ExceptionMessages.ERR_20001, e.getMessage()));
                }
            }

            @Override
            public void stop() {

            }
        });
        ExecutorPool.submit(task);
    }

    /**
     * find history data in new thead
     *
     * @param filePath      currten choose file
     * @param searchKeys    currten search fields
     * @param groupKeys     currten choose groups
     * @param groupValue    currten group
     * @param type          currten type
     * @param testItemNames currten choose item
     * @param uslAndLslDto  currten usl and lsl
     */
    public void findHistory(List<String> filePath, List<DynSearchFieldDto> searchKeys, List<String> groupKeys, String groupValue, Integer type, List<String> testItemNames, UslAndLslDto uslAndLslDto) {
        boolean isWorking = ApplicationBeanUtils.getBean(MainStateBar.class).getProcessPanel().isWorking(ProcessConstant.YIELD_HISTORY_TASK);
        if (isWorking) {
            throw new UIException("This task is already working now.");
        }
        EventBusUtils.post(new StatusBarProcessCreateTaskEvent(ProcessConstant.YIELD_HISTORY_TASK));

        ExecutorTask task = new ExecutorTask(ProcessConstant.YIELD_HISTORY_TASK, new ExecutorTask.Work() {
            @Override
            public void execute() {
                try {
                    YieldItemParamDto yieldItemParamDto = itemDataChangeInto(uslAndLslDto);
                    YieldHistoryDto yieldHistoryDto = reportService.getYieldHistory(filePath, searchKeys, groupKeys, groupValue, type, testItemNames, yieldItemParamDto);

                    if (!ApplicationBeanUtils.getBean(MainStateBar.class).getProcessPanel().isProcessTaskEmpty()) {
                        EventBusUtils.post(new ExecutorTaskFinishEvent(ProcessConstant.YIELD_HISTORY_TASK, yieldHistoryDto));
                        EventBusUtils.post(new StatusBarProcessFinishTaskEvent(ProcessConstant.YIELD_HISTORY_TASK, false));
                    }
                } catch (ApplicationException e) {
                    EventBusUtils.post(new StatusBarProcessChangeEvent(ProcessConstant.YIELD_HISTORY_TASK, e.getFullMessage()).level(ProcessConstant.ERROR));
                } catch (Exception e) {
                    EventBusUtils.post(new ThrowExceptionEvent(ExceptionMessages.ERR_20001, e.getMessage()));
                }
            }

            @Override
            public void stop() {

            }
        });
        ExecutorPool.submit(task);
    }

    /**
     * find usl and lsl by test of file
     *
     * @param filePaths     currten choose file
     * @param testItemNames currten choose item
     * @return usl and lsl
     */
    public UslAndLslDto findYieldItemParam(List<String> filePaths, List<String> testItemNames) {
        UslAndLslDto uslAndLslDto = new UslAndLslDto();
        try {
            YieldItemParamDto yieldItemParamDto = reportService.getYieldItemParam(filePaths, testItemNames);
            if (yieldItemParamDto.getUsl() != null) {
                uslAndLslDto.setUslValue(yieldItemParamDto.getUsl().toString());
            }
            if (yieldItemParamDto.getLsl() != null) {
                uslAndLslDto.setLslValue(yieldItemParamDto.getLsl().toString());
            }
        } catch (ApplicationException e) {

            logger.error("GrrController UslAndLsl error :" + e.getFullMessage());
            EventBusUtils.post(new ThrowExceptionEvent(e.getFullMessage()));
        } catch (Exception e) {
            logger.error("GrrController UslAndLsl error :" + e.getMessage());
            EventBusUtils.post(new ThrowExceptionEvent(ExceptionMessages.ERR_20001, e.getMessage()));
        }
        return uslAndLslDto;
    }

    /**
     * export yield table to Excel file
     *
     * @param filePath      currten choose file
     * @param searchKeys    currten search fields
     * @param groupKeys     currten choose groups
     * @param testItemNames currten choose item
     * @param uslAndLslDto  currten usl and lsl
     */
    public void exportSummary(List<String> filePath, List<DynSearchFieldDto> searchKeys, List<String> groupKeys, List<String> testItemNames, UslAndLslDto uslAndLslDto) {
        boolean isWorking = ApplicationBeanUtils.getBean(MainStateBar.class).getProcessPanel().isWorking(ProcessConstant.YIELD_EXPORT_FILE);
        if (isWorking) {
            throw new UIException("This task is already working now.");
        }
        EventBusUtils.post(new StatusBarProcessCreateTaskEvent(ProcessConstant.YIELD_EXPORT_FILE, true));

        ExecutorTask task = new ExecutorTask(ProcessConstant.YIELD_EXPORT_FILE, new ExecutorTask.Work() {
            @Override
            public void execute() {
                try {
                    YieldItemParamDto yieldItemParamDto = itemDataChangeInto(uslAndLslDto);
                    String savePath = reportService.exportSummary(filePath, searchKeys, groupKeys, testItemNames, yieldItemParamDto);

                    if (!ApplicationBeanUtils.getBean(MainStateBar.class).getProcessPanel().isProcessTaskEmpty()) {
                        EventBusUtils.post(new ExecutorTaskFinishEvent(ProcessConstant.YIELD_EXPORT_FILE, savePath));
                        EventBusUtils.post(new StatusBarProcessFinishTaskEvent(ProcessConstant.YIELD_EXPORT_FILE));
                    }
                } catch (ApplicationException e) {
                    EventBusUtils.post(new StatusBarProcessChangeEvent(ProcessConstant.YIELD_EXPORT_FILE, e.getFullMessage()).level(ProcessConstant.ERROR));
                } catch (Exception e) {
                    EventBusUtils.post(new ThrowExceptionEvent(ExceptionMessages.ERR_20001, e.getMessage()));
                }
            }

            @Override
            public void stop() {

            }
        });
        ExecutorPool.submit(task);
    }


    /**
     * export all data to Excel file
     *
     * @param filePath      currten choose file
     * @param searchKeys    currten search fields
     * @param groupKeys     currten choose groups
     * @param testItemNames currten choose item
     * @param uslAndLslDto  currten usl and lsl
     */
    public void exportSummaryAndDetail(List<String> filePath, List<DynSearchFieldDto> searchKeys, List<String> groupKeys, List<String> testItemNames, UslAndLslDto uslAndLslDto) {
        boolean isWorking = ApplicationBeanUtils.getBean(MainStateBar.class).getProcessPanel().isWorking(ProcessConstant.YIELD_EXPORT_FILE);
        if (isWorking) {
            throw new UIException("This task is already working now.");
        }
        EventBusUtils.post(new StatusBarProcessCreateTaskEvent(ProcessConstant.YIELD_EXPORT_FILE, true));

        ExecutorTask task = new ExecutorTask(ProcessConstant.YIELD_EXPORT_FILE, new ExecutorTask.Work() {
            @Override
            public void execute() {
                try {
                    YieldItemParamDto yieldItemParamDto = itemDataChangeInto(uslAndLslDto);
                    String savePath = reportService.exportSummaryAndDetail(filePath, searchKeys, groupKeys, testItemNames, yieldItemParamDto);

                    if (!ApplicationBeanUtils.getBean(MainStateBar.class).getProcessPanel().isProcessTaskEmpty()) {
                        EventBusUtils.post(new ExecutorTaskFinishEvent(ProcessConstant.YIELD_EXPORT_FILE, savePath));
                        EventBusUtils.post(new StatusBarProcessFinishTaskEvent(ProcessConstant.YIELD_EXPORT_FILE));
                    }
                } catch (ApplicationException e) {
                    EventBusUtils.post(new StatusBarProcessChangeEvent(ProcessConstant.YIELD_EXPORT_FILE, e.getFullMessage()).level(ProcessConstant.ERROR));
                } catch (Exception e) {
                    EventBusUtils.post(new ThrowExceptionEvent(ExceptionMessages.ERR_20001, e.getMessage()));
                }
            }

            @Override
            public void stop() {

            }
        });
        ExecutorPool.submit(task);

    }

    /**
     * find item , search fields and groups
     *
     * @param fileNames currtnt choose file
     */
    public void findSearchKey(List<String> fileNames) {
        boolean isWorking = ApplicationBeanUtils.getBean(MainStateBar.class).getProcessPanel().isWorking(ProcessConstant.YIELD_DECODE_FILE);
        if (isWorking) {
            throw new UIException("This task is already working now.");
        }
        EventBusUtils.post(new StatusBarProcessCreateTaskEvent(ProcessConstant.YIELD_DECODE_FILE));

        ExecutorTask task = new ExecutorTask(ProcessConstant.YIELD_DECODE_FILE, new ExecutorTask.Work() {
            @Override
            public void execute() {
                try {
                    FieldDataSourceDto dto = reportService.findFieldDataSource(fileNames);
                    if (!ApplicationBeanUtils.getBean(MainStateBar.class).getProcessPanel().isProcessTaskEmpty()) {
                        EventBusUtils.post(new ExecutorTaskFinishEvent(ProcessConstant.YIELD_DECODE_FILE, dto));
                        EventBusUtils.post(new StatusBarProcessFinishTaskEvent(ProcessConstant.YIELD_DECODE_FILE, false));
                    }
                } catch (ApplicationException e) {
                    EventBusUtils.post(new StatusBarProcessChangeEvent(ProcessConstant.YIELD_DECODE_FILE, e.getFullMessage()).level(ProcessConstant.ERROR));
                } catch (Exception e) {
                    EventBusUtils.post(new ThrowExceptionEvent(ExceptionMessages.ERR_20001, e.getMessage()));
                }
            }

            @Override
            public void stop() {

            }
        });
        ExecutorPool.submit(task);
    }

    /*
     *UslAndLslDto changeinto YieldItemParamDto
     */
    private YieldItemParamDto itemDataChangeInto(UslAndLslDto uslAndLslDto) {

        YieldItemParamDto yieldItemParamDto = null;
        try {
            if (uslAndLslDto != null) {
                yieldItemParamDto = new YieldItemParamDto();
                if (uslAndLslDto.getUslValue() != null) {
                    yieldItemParamDto.setUsl(Double.valueOf(uslAndLslDto.getUslValue()));
                }
                if (uslAndLslDto.getLslValue() != null) {
                    yieldItemParamDto.setLsl(Double.valueOf(uslAndLslDto.getLslValue()));
                }
            }
        } catch (ApplicationException e) {
            logger.error("YieldController Item error :" + e.getFullMessage());
            EventBusUtils.post(new ThrowExceptionEvent(e.getFullMessage()));
        } catch (Exception e) {
            logger.error("YieldController Item error :" + e.getMessage());
            EventBusUtils.post(new ThrowExceptionEvent(ExceptionMessages.ERR_20001, e.getMessage()));
        }
        return yieldItemParamDto;
    }

}

